﻿#pragma execution_character_set("UTF-8")

#include <QLabel>
#include <QTextStream>
#include <QFileDialog>
#include <qDebug>
#include <QVariant>
#include <QMessageBox>
#include <QAction>
#include <QMenu>
#include <QtCore/QException>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QComboBox>
#include <QStandardPaths>
#include <QProcess>
#include <QDesktopServices>
#include <QMessageBox>
#include <QThread>
#include <QButtonGroup>
#include <QTcpSocket>
#include <QHostAddress>
#include <QTableWidget>
#include <qmath.h>
#include <Windows.h>
#include "import_gui.h"
#include "FY5400.H"

#pragma comment(lib,"FY5400_64.lib")
HANDLE hDev = INVALID_HANDLE_VALUE;//FY5400的句柄

import_gui::import_gui(QWidget* parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);
    setWindowTitle("Excel生成工具");

    setWindowFlag(Qt::WindowMaximizeButtonHint, false);

    m_tcpClient = new QTcpSocket(this); //创建socket变量
    connect(m_tcpClient, SIGNAL(connected()), this, SLOT(onConnected()));
    connect(m_tcpClient, SIGNAL(readyRead()), this, SLOT(onSocketReadyRead()));
    connect(m_tcpClient, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
        this, SLOT(onSocketStateChange(QAbstractSocket::SocketState)));

    ui.tabWidget->setCurrentIndex(2);
    ui.productSerialLineEdit->setText(QLatin1Literal(""));
    ui.workOrderNoLineEdit->setText(QLatin1Literal(""));

    connect(ui.importPushButton, &QPushButton::pressed, this, &import_gui::importDataProcess);
    connect(ui.writePushButton, &QPushButton::pressed, this, &import_gui::writeExcelProcess);
    connect(ui.excelTemplatePushButton, &QPushButton::pressed, this, &import_gui::setExcelTemplateProcess);
    connect(ui.restartPushButton, &QPushButton::pressed, [=]() {
        if (hDev != INVALID_HANDLE_VALUE) {
            FY5400_CloseDevice(hDev);
            hDev = INVALID_HANDLE_VALUE;
        }

        QThread::msleep(500);
        hDev = FY5400_OpenDevice(0);
        if (hDev == INVALID_HANDLE_VALUE) {
            ui.statusLabel->setText("板卡打开错误");
            ui.statusLabel->setStyleSheet(QString::fromUtf8("color: rgb(255, 0, 0);"));
            QMessageBox::warning(this, "Error", "获得句柄错误,请检查驱动是否正常");
        } else {
            auto value = ui.selectComboBox->currentText();
            if (cardSendCommand(m_currentImportIndex)) {
                ui.sendStatusLabel->setText("发送成功: " + value);
                ui.sendStatusLabel->setStyleSheet(QString::fromUtf8("color: rgb(0, 85, 255);"));
            } else {
                ui.sendStatusLabel->setText("发送失败: " + value);
                ui.sendStatusLabel->setStyleSheet(QString::fromUtf8("color: rgb(255, 0, 0);"));
            }

            ui.statusLabel->setText("板卡正常打开");
            ui.statusLabel->setStyleSheet(QString::fromUtf8("color: rgb(0, 255, 0);"));
        }
    });
    connect(ui.closePushButton, &QPushButton::pressed, [=]() {
        if (hDev != INVALID_HANDLE_VALUE) {
            FY5400_CloseDevice(hDev);
            hDev = INVALID_HANDLE_VALUE;
        }

        ui.statusLabel->setText("板卡没有打开");
        ui.statusLabel->setStyleSheet(QString::fromUtf8("color: rgb(255, 0, 0);"));
    });

    QString oIpRange = "(?:[0-1]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])";
    QRegExp oIpRegex("^" + oIpRange
        + "\\." + oIpRange
        + "\\." + oIpRange
        + "\\." + oIpRange + "$");
    ui.ipLineEdit->setValidator(new QRegExpValidator(oIpRegex));
    ui.localIPLineEdit->setValidator(new QRegExpValidator(oIpRegex));
    ui.ipLineEdit2->setValidator(new QRegExpValidator(oIpRegex));
    connect(ui.ipLineEdit2, &QLineEdit::editingFinished, [&] {
        if (m_remoteIP != ui.ipLineEdit2->text()) {
            m_remoteIP = ui.ipLineEdit2->text();
            ui.ipLineEdit->setText(m_remoteIP);
            saveSetting();
        }
    });
    connect(ui.ipLineEdit, &QLineEdit::editingFinished, [&] {
        if (m_remoteIP != ui.ipLineEdit->text()) {
            m_remoteIP = ui.ipLineEdit->text();
            ui.ipLineEdit2->setText(m_remoteIP);
            saveSetting();
        }
    });
    connect(ui.portLineEdit2, &QLineEdit::editingFinished, [&] {
        if (m_remotePort != ui.portLineEdit2->text()) {
            m_remotePort = ui.portLineEdit2->text();
            saveSetting();
        }
    });
    connect(ui.localIPLineEdit, &QLineEdit::editingFinished, [&] {
        if (m_localIP != ui.localIPLineEdit->text()) {
            m_localIP = ui.localIPLineEdit->text();
            saveSetting();
        }
    });
    connect(ui.productSerialLineEdit, &QLineEdit::editingFinished, [&] {
        importedData.productSerial = ui.productSerialLineEdit->text();
    });
    connect(ui.workOrderNoLineEdit, &QLineEdit::editingFinished, [&] {
        importedData.workOrder = ui.workOrderNoLineEdit->text();
    });
    connect(ui.selectSharePushButton, &QPushButton::pressed, this, &import_gui::selectShareDir);
    connect(ui.remoteImportPushButton, &QPushButton::pressed, this, &import_gui::importFromRemote);
    menu = new QMenu(this);
    QStringList name;
    name << QString::fromLocal8Bit("银色") << QString::fromLocal8Bit("蓝色") << QString::fromLocal8Bit("浅蓝色")
        << QString::fromLocal8Bit("深蓝色") << QString::fromLocal8Bit("灰色") << QString::fromLocal8Bit("浅灰色")
        << QString::fromLocal8Bit("深灰色") << QString::fromLocal8Bit("黑色")
        << QString::fromLocal8Bit("浅黑色") << QString::fromLocal8Bit("深黑色") << QString::fromLocal8Bit("PS黑色")
        << QString::fromLocal8Bit("黑色扁平") << QString::fromLocal8Bit("白色扁平");

    foreach(QString str, name)
    {
        QAction* action = new QAction(str, this);
        menu->addAction(action);
    }

    connect(this, &import_gui::clicked, this, [&](Qt::MouseButton, Qt::KeyboardModifiers modifiers) {
        if (modifiers & Qt::ShiftModifier) {
            auto action = menu->exec(QCursor::pos());
            changeStyle(action);
        }
    });

    QObject::connect(ui.groupNoComboBox, static_cast<void (QComboBox::*)(int index)>(&QComboBox::currentIndexChanged), this, &import_gui::currentIndexChangedHandler);

    loadSetting();
    initMappedView();
    QObject::connect(ui.confirmPushButton, &QPushButton::pressed, this, &import_gui::updateFileMapped);

    ui.ipLineEdit->setText(m_remoteIP);
    ui.ipLineEdit2->setText(m_remoteIP);
    ui.portLineEdit2->setText(m_remotePort);
    ui.localIPLineEdit->setText(m_localIP);
    ui.shareDirLineEdit->setText(m_shareDir);

    m_contentItems << "频率";
    m_contentItems << "S11幅度";
    m_contentItems << "S11相位";
    m_contentItems << "S21幅度";
    m_contentItems << "S21相位";
    m_contentItems << "S12幅度";
    m_contentItems << "S12相位";
    m_contentItems << "S22幅度";
    m_contentItems << "S22相位";

    const auto appPath = qApp->applicationDirPath();
    const auto toolPath = appPath + "/getdata";
    m_toolName = toolPath + "/GetData5071.exe";
    m_configName = toolPath + "/config.dat";
    m_markName = toolPath + "/Mark.dat";
    m_toolProcess = new QProcess(this);
    connect(m_toolProcess, static_cast<void (QProcess::*)(int)>(&QProcess::finished), [=](int exitCode) {
        {
            QFile file(m_markName);
            if (file.exists()
                && file.open(QIODevice::ReadOnly)) {
                QTextStream in(&file);
                QString rtn;
                in >> rtn;
                file.flush();
                file.close();

                bool ok = false;
                const auto rtn1 = rtn.toInt(&ok);
                if (ok) {
                    if (rtn1 > 0) {
                        QMessageBox::information(this, "成功", "导入数据成功");
                    } else {
                        QMessageBox::information(this, "失败", "导入数据失败");
                    }
                }
            }
        }
    });

    QButtonGroup* btnGroup = new QButtonGroup(this);
    btnGroup->addButton(ui.lowRadioButton);
    btnGroup->addButton(ui.highRadioButton);
    btnGroup->addButton(ui.roomRadioButton);
    btnGroup->setId(ui.lowRadioButton, 0);
    btnGroup->setId(ui.highRadioButton, 1);
    btnGroup->setId(ui.roomRadioButton, 2);
    ui.lowRadioButton->setChecked(true);
    m_tempStatus = TempStatus::Low;
    connect(btnGroup, &QButtonGroup::idPressed, this, &import_gui::tempStatusToggled);

    ui.selectComboBox->clear();
    for (auto i = static_cast<int>(ItemIndex::Start) + 1; i < static_cast<int>(ItemIndex::End);) {
        auto item = m_excelMapped[static_cast<ItemIndex>(i)];
        auto index = item.lastIndexOf("_");
        item = item.left(index);
        ui.selectComboBox->addItem(item);
        i += 3;
    }
    ui.selectComboBox->setCurrentIndex(0);
    m_currentImportIndex = m_excelMapped.firstKey();
    auto configString = QString("TCPIP0::%1::inst0::INSTR,'\\\\%2\\%3\\%4.s2p'")
        .arg(m_remoteIP).arg(m_localIP).arg(m_shareDir).arg(m_fileMapped.value(m_currentImportIndex));
    ui.configLineEdit->setText(configString);
    QObject::connect(ui.selectComboBox, static_cast<void (QComboBox::*)(const QString&)>(&QComboBox::currentIndexChanged),
        this, &import_gui::selectCurrentIndexChangedHandler);

    QObject::connect(ui.connectPushButton, &QPushButton::pressed, [&]() {
        bool ok = false;
        QString ip = m_remoteIP;
        quint16 port = m_remotePort.toUShort(&ok);
        if (ok) {
            /*if (m_tcpClient->state() == QAbstractSocket::ConnectedState)*/
            {
                m_tcpClient->abort();
                QThread::msleep(200);
            }
            m_tcpClient->connectToHost(ip, port);
        }
    });
    for (auto i = static_cast<int>(ItemIndex::Start) + 1; i < static_cast<int>(ItemIndex::End); ++i) {
        QString str = QString("%1.sta").arg(i);
        ui.stateComboBox->addItem(str);
    }
    ui.stateComboBox->setCurrentIndex(0);
    QObject::connect(ui.statePushButton, &QPushButton::pressed, [&]() {
        if (m_tcpClient->state() == QAbstractSocket::ConnectedState) {
            QString aFileName;
            aFileName = ui.stateComboBox->currentText();  //读取选择的文件名

            QByteArray vna_name = ":MMEM:LOAD \"D:\\";  // :MMEM:LOAD是仪器的SCPI指令
                                                      // 注意LOAD后面有空格，否则就不是LOAD单词
                                                      //文件名和路径名是字符串，所以必须有双引号
                                                      //前面的\"表示” (见C语言规则)
                                                      //后面的\\表示\ (见C语言规则)
            vna_name.append(aFileName);   //将状态文件名加到上面的字符串中
            vna_name.append("\"  \n");    //在串尾加上”和换行符\n (见C语言规则)
                                          //这时字符串就是 :MMEM:LOAD "D:\state01.sta \n"
                                          //这就是完整的调用状态文件的SCPI指令
            m_tcpClient->write(vna_name);  //发给仪器

            QThread::msleep(100); //稍等一下  看看有没有文件错误, 这条指令延时可以不用
            m_tcpClient->write(":SYST:ERR? \n");  //查看刚才发的文件名有没有错
        }
    });
    ui.commandComboBox->addItem(QString("*IDN?"));
    ui.commandComboBox->addItem(QString(":DISP:WIND1:Y:DIV 8"));
    ui.commandComboBox->addItem(QString(":DISP:WIND1:Y:DIV 10"));
    ui.commandComboBox->addItem(QString(":CALC1:DATA:FDATA?"));
    ui.commandComboBox->setCurrentIndex(0);
    QObject::connect(ui.commandPushButton, &QPushButton::pressed, [&]() {
        if (m_tcpClient->state() == QAbstractSocket::ConnectedState) {
            QString  msg = ui.commandComboBox->currentText();
            ui.textPlainTextEdit->appendPlainText("[out:] " + msg);

            QByteArray  str = msg.toUtf8();
            str.append(" \n");
            m_tcpClient->write(str);
        }
    });
    QObject::connect(ui.clearPushButton, &QPushButton::pressed, [&]() {
        ui.textPlainTextEdit->clear();
    });
}

void import_gui::importDataProcess()
{
    QFileDialog dialog(this, "选择.s2p文件所在文件夹", nullptr);
    dialog.setAcceptMode(QFileDialog::AcceptOpen);
    dialog.setFileMode(QFileDialog::DirectoryOnly);
    QUrl url;
    bool rtn = false;
    if (dialog.exec()) {
        auto urls = dialog.selectedUrls();
        if (urls.size() > 0) {
            url = urls[0];
            rtn = true;
        }
    }

    if (!rtn) return;

    importedData.importItemsMap.clear();
    ui.groupNoComboBox->clear();
    ui.dataTableWidget->clearContents();
    ui.dataTableWidget->setRowCount(0);
    ui.dataTableWidget->setColumnCount(0);
    qApp->processEvents();

    const auto fileDir = url.toLocalFile();
    ui.importLineEdit->setText(fileDir);
    if (m_fileMapped.size() > 0) {
        for (auto&& baseName : m_fileMapped) {
            const auto filePath = fileDir + "/" + baseName + ".S2P";
            if (QFile::exists(filePath)) {
                ui.groupNoComboBox->addItem(baseName + ".S2P");
                QFile file(filePath);
                try {
                    file.open(QIODevice::ReadOnly);
                    QTextStream in(&file);
                    in.setCodec("utf8");
                    in.readLine();
                    in.readLine();
                    in.readLine();
                    in.readLine();
                    in.readLine();
                    in.readLine();
                    in.readLine();
                    in.readLine();
                    //auto content = in.readLine();
                    QRegExp regex_str("\\s+");
                    //auto contentItems = content.split(regex_str);

                    QMap<qulonglong, ImportDataItem> importItems;
                    while (!in.atEnd()) {
                        try {
                            auto rowContent = in.readLine();
                            auto rowContents = rowContent.split(regex_str);
                            if (rowContents.size() != 9) continue;

                            ImportDataItem item;
                            item.frequency = rowContents[0];
                            item.S11Amplitude = rowContents[1];
                            item.S11Phase = rowContents[2];
                            item.S21Amplitude = rowContents[3];
                            item.S21Phase = rowContents[4];
                            item.S12Amplitude = rowContents[5];
                            item.S12Phase = rowContents[6];
                            item.S22Amplitude = rowContents[7];
                            item.S22Phase = rowContents[8];
                            item.valid = true;
                            const auto freq = item.frequency.toULongLong();
                            importItems.insert(freq, item);
                        } catch (const QException& e) {
                            qDebug() << e.what();
                        }
                    };
                    importedData.importItemsMap.insert(m_fileMapped.key(baseName), importItems);
                    importItems.clear();

                } catch (const QException& e) {
                    qDebug() << e.what();
                }
                file.close();
            }
        }
        QThread::msleep(300);

        if (ui.groupNoComboBox->count() > 0) {
            emit ui.groupNoComboBox->currentIndexChanged(0);
        }
    }
}

void import_gui::writeExcelProcess()
{
    if (importedData.importItemsMap.size() <= 0) {
        QMessageBox::information(this, QString::fromLocal8Bit("缺少数据"), QString::fromLocal8Bit("请先导入数据！"));
        return;
    }

    if (ui.templateLineEdit->text().isEmpty()) {
        QMessageBox::information(this, QString::fromLocal8Bit("缺少Excel模板"), QString::fromLocal8Bit("请先选择Excel模板文件"));
        return;
    }

    auto fileName = ui.templateLineEdit->text();
    if (m_xlsxR) {
        delete m_xlsxR;
        m_xlsxR = nullptr;
    }
    m_xlsxR = new QXlsx::Document(fileName);
    if (m_xlsxR->load()) // load excel file
    {
        auto sheet0 = m_xlsxR->workbook()->sheet(0);
        auto sheetName = sheet0->sheetName();
        m_xlsxR->selectSheet(sheetName);

        auto productNo = importedData.productSerial;
        int row = 11; int col = 1;
        int row2 = 36; int col2 = 1;
        if (!productNo.isEmpty()
            && !productNo.isNull()) {
            QVariant writeValue = QString("型号：  %1                                                           数量：1只")
                .arg(productNo);
            m_xlsxR->write(row, col, writeValue);

            writeValue = QString("型号：  %1")
                .arg(productNo);
            m_xlsxR->write(row2, col2, writeValue);
        }
        auto workOrderNo = importedData.workOrder;
        if (!workOrderNo.isEmpty()
            && !workOrderNo.isNull()) {
            row = 5; col = 1;
            QVariant writeValue = QString("工单号：%1")
                .arg(workOrderNo);
            m_xlsxR->write(row, col, writeValue);
        }
        for (auto&& item : m_excelMapped) {
            const auto key = m_excelMapped.key(item);
            if (!importedData.importItemsMap.contains(key)) continue;

            switch (key) {
            case ItemIndex::I_SC_S_L:
                write_I_SC_S_L(m_xlsxR, key, 14, Status::Send);
                break;
            case ItemIndex::I_SC_S_H:
                write_I_SC_S_L(m_xlsxR, key, 15, Status::Send);
                break;
            case ItemIndex::I_SC_S_R:
                write_I_SC_S_L(m_xlsxR, key, 16, Status::Send);
                break;
            case ItemIndex::I_SC_R_L:
                write_I_SC_S_L(m_xlsxR, key, 17, Status::Receive);
                break;
            case ItemIndex::I_SC_R_H:
                write_I_SC_S_L(m_xlsxR, key, 18, Status::Receive);
                break;
            case ItemIndex::I_SC_R_R:
                write_I_SC_S_L(m_xlsxR, key, 19, Status::Receive);
                break;
            case ItemIndex::Q_SC_S_L:
                write_I_SC_S_L(m_xlsxR, key, 20, Status::Send);
                break;
            case ItemIndex::Q_SC_S_H:
                write_I_SC_S_L(m_xlsxR, key, 21, Status::Send);
                break;
            case ItemIndex::Q_SC_S_R:
                write_I_SC_S_L(m_xlsxR, key, 22, Status::Send);
                break;
            case ItemIndex::Q_SC_R_L:
                write_I_SC_S_L(m_xlsxR, key, 23, Status::Receive);
                break;
            case ItemIndex::Q_SC_R_H:
                write_I_SC_S_L(m_xlsxR, key, 24, Status::Receive);
                break;
            case ItemIndex::Q_SC_R_R:
                write_I_SC_S_L(m_xlsxR, key, 25, Status::Receive);
                break;
            case ItemIndex::SC_RS_TI_I_L:
                write_SC_RS_TI_I_L(m_xlsxR, key, 26, Page::First);
                break;
            case ItemIndex::SC_RS_TI_I_H:
                write_SC_RS_TI_I_L(m_xlsxR, key, 27, Page::First);
                break;
            case ItemIndex::SC_RS_TI_I_R:
                write_SC_RS_TI_I_L(m_xlsxR, key, 28, Page::First);
                break;
            case ItemIndex::SC_RS_TI_Q_L:
                write_SC_RS_TI_I_L(m_xlsxR, key, 26, Page::First);
                break;
            case ItemIndex::SC_RS_TI_Q_H:
                write_SC_RS_TI_I_L(m_xlsxR, key, 27, Page::First);
                break;
            case ItemIndex::SC_RS_TI_Q_R:
                write_SC_RS_TI_I_L(m_xlsxR, key, 28, Page::First);
                break;
            case ItemIndex::I_X_S_L:
                write_I_X_S_L(m_xlsxR, key, 39, Status::Send);
                break;
            case ItemIndex::I_X_S_H:
                write_I_X_S_L(m_xlsxR, key, 40, Status::Send);
                break;
            case ItemIndex::I_X_S_R:
                write_I_X_S_L(m_xlsxR, key, 41, Status::Send);
                break;
            case ItemIndex::I_X_R_L:
                write_I_X_S_L(m_xlsxR, key, 42, Status::Receive);
                break;
            case ItemIndex::I_X_R_H:
                write_I_X_S_L(m_xlsxR, key, 43, Status::Receive);
                break;
            case ItemIndex::I_X_R_R:
                write_I_X_S_L(m_xlsxR, key, 44, Status::Receive);
                break;
            case ItemIndex::Q_X_S_L:
                write_I_X_S_L(m_xlsxR, key, 45, Status::Send);
                break;
            case ItemIndex::Q_X_S_H:
                write_I_X_S_L(m_xlsxR, key, 46, Status::Send);
                break;
            case ItemIndex::Q_X_S_R:
                write_I_X_S_L(m_xlsxR, key, 47, Status::Send);
                break;
            case ItemIndex::Q_X_R_L:
                write_I_X_S_L(m_xlsxR, key, 48, Status::Receive);
                break;
            case ItemIndex::Q_X_R_H:
                write_I_X_S_L(m_xlsxR, key, 49, Status::Receive);
                break;
            case ItemIndex::Q_X_R_R:
                write_I_X_S_L(m_xlsxR, key, 50, Status::Receive);
                break;
            case ItemIndex::X_RS_TI_I_L:
                write_SC_RS_TI_I_L(m_xlsxR, key, 51, Page::Second);
                break;
            case ItemIndex::X_RS_TI_I_H:
                write_SC_RS_TI_I_L(m_xlsxR, key, 52, Page::Second);
                break;
            case ItemIndex::X_RS_TI_I_R:
                write_SC_RS_TI_I_L(m_xlsxR, key, 53, Page::Second);
                break;
            case ItemIndex::X_RS_TI_Q_L:
                write_SC_RS_TI_I_L(m_xlsxR, key, 51, Page::Second);
                break;
            case ItemIndex::X_RS_TI_Q_H:
                write_SC_RS_TI_I_L(m_xlsxR, key, 52, Page::Second);
                break;
            case ItemIndex::X_RS_TI_Q_R:
                write_SC_RS_TI_I_L(m_xlsxR, key, 53, Page::Second);
                break;
            default:
                break;
            }
        }

        QThread::msleep(500);
        QFileDialog dialog(this, QString::fromLocal8Bit("另保存Excel文件"), nullptr, "*.xlsx");
        dialog.setAcceptMode(QFileDialog::AcceptSave);
        dialog.setFileMode(QFileDialog::AnyFile);
        bool rtn = false;
        QString fileName;
        if (dialog.exec()) {
            auto fileNames = dialog.selectedFiles();
            if (fileNames.size() > 0) {
                fileName = fileNames[0];
                rtn = true;
            }
        }
        if (rtn) {
            m_xlsxR->saveAs(fileName);
            QMessageBox::information(this, QString::fromLocal8Bit("成功"), QString::fromLocal8Bit("写入Excel成功！"));
            QDesktopServices::openUrl(QUrl::fromLocalFile(fileName));
        }
    }

    if (m_xlsxR) {
        delete m_xlsxR;
        m_xlsxR = nullptr;
    }
}

void import_gui::setExcelTemplateProcess()
{
    QFileDialog dialog(this, QString::fromLocal8Bit("打开Excel模板"), nullptr, "*.xlsx");
    dialog.setAcceptMode(QFileDialog::AcceptOpen);
    dialog.setFileMode(QFileDialog::AnyFile);
    QString fileName;
    bool rtn = false;
    if (dialog.exec()) {
        auto fileNames = dialog.selectedFiles();
        if (fileNames.size() > 0) {
            fileName = fileNames[0];
            ui.templateLineEdit->setText(fileName);
        }
    }
}

void import_gui::changeStyle(QAction* act)
{
    if (act == nullptr) return;

    QString name = act->text();
    QString qssFile = ":/qss/blue.css";

    if (name == QString::fromLocal8Bit("银色")) {
        qssFile = ":/qss/silvery.css";
        setStyle(import_gui::Style_Silvery);
    } else if (name == QString::fromLocal8Bit("蓝色")) {
        qssFile = ":/qss/blue.css";
        setStyle(import_gui::Style_Blue);
    } else if (name == QString::fromLocal8Bit("浅蓝色")) {
        qssFile = ":/qss/lightblue.css";
        setStyle(import_gui::Style_LightBlue);
    } else if (name == QString::fromLocal8Bit("深蓝色")) {
        qssFile = ":/qss/darkblue.css";
        setStyle(import_gui::Style_DarkBlue);
    } else if (name == QString::fromLocal8Bit("灰色")) {
        qssFile = ":/qss/gray.css";
        setStyle(import_gui::Style_Gray);
    } else if (name == QString::fromLocal8Bit("浅灰色")) {
        qssFile = ":/qss/lightgray.css";
        setStyle(import_gui::Style_LightGray);
    } else if (name == QString::fromLocal8Bit("深灰色")) {
        qssFile = ":/qss/darkgray.css";
        setStyle(import_gui::Style_DarkGray);
    } else if (name == QString::fromLocal8Bit("黑色")) {
        qssFile = ":/qss/black.css";
        setStyle(import_gui::Style_Black);
    } else if (name == QString::fromLocal8Bit("浅黑色")) {
        qssFile = ":/qss/lightblack.css";
        setStyle(import_gui::Style_LightBlack);
    } else if (name == QString::fromLocal8Bit("深黑色")) {
        qssFile = ":/qss/darkblack.css";
        setStyle(import_gui::Style_DarkBlack);
    } else if (name == QString::fromLocal8Bit("PS黑色")) {
        qssFile = ":/qss/psblack.css";
        setStyle(import_gui::Style_PSBlack);
    } else if (name == QString::fromLocal8Bit("黑色扁平")) {
        qssFile = ":/qss/flatblack.css";
        setStyle(import_gui::Style_FlatBlack);
    } else if (name == QString::fromLocal8Bit("白色扁平")) {
        qssFile = ":/qss/flatwhite.css";
        setStyle(import_gui::Style_FlatWhite);
    }
}

void import_gui::updateFileMapped()
{
    auto i = 0;
    QList<QString> fileBases;
    for (int index = static_cast<int>(ItemIndex::Start) + 1; index < static_cast<int>(ItemIndex::End); ++index) {
        const auto itemData = ui.fileMapTableWidget->item(i, 2);
        const auto itemIndex = static_cast<ItemIndex>(index);
        const auto text = itemData->text();
        if (fileBases.contains(text)) {
            const auto rtn = QMessageBox::critical(this, "映射错误", "存在相同文件名的映射，请重新选择！", QMessageBox::Ok);
            fileBases.clear();
            return;
        }

        fileBases.append(text);
        ++i;
    }

    auto j = 0;
    for (int index = static_cast<int>(ItemIndex::Start) + 1; index < static_cast<int>(ItemIndex::End); ++index) {
        const auto itemData = ui.fileMapTableWidget->item(j, 2);
        const auto itemIndex = static_cast<ItemIndex>(index);
        m_fileMapped[itemIndex] = itemData->text();
        ++j;
    }

    if (saveSetting()) {
        QMessageBox::information(this, "成功", "完成文件映射更新！");
    }
}

void import_gui::currentIndexChangedHandler(int currentIndex)
{
    if (importedData.importItemsMap.size() <= 0) return;

    QString index = ui.groupNoComboBox->currentText();
    if (index.contains(".S2P", Qt::CaseInsensitive)) {
        index.remove(".S2P", Qt::CaseInsensitive);
    }
    const auto key = m_fileMapped.key(index, ItemIndex::Start);
    if (static_cast<unsigned int>(key) > static_cast<unsigned int>(ItemIndex::Start)
        && static_cast<unsigned int>(key) < static_cast<unsigned int>(ItemIndex::End)) {
        const auto importItems = importedData.importItemsMap.value(key, QMap<qulonglong, ImportDataItem>());
        if (importItems.size() > 0) {
            ui.dataTableWidget->clearContents();
            auto headerSize = m_contentItems.size();
            ui.dataTableWidget->setColumnCount(headerSize);
            ui.dataTableWidget->setHorizontalHeaderLabels(m_contentItems);
            ui.dataTableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
            ui.dataTableWidget->setRowCount(0);
            qApp->processEvents(QEventLoop::AllEvents, 100);
            for (auto&& item : importItems) {
                auto i = ui.dataTableWidget->rowCount();
                ui.dataTableWidget->insertRow(i);
                ui.dataTableWidget->setItem(i, 0, new QTableWidgetItem(item.frequency));
                ui.dataTableWidget->setItem(i, 1, new QTableWidgetItem(item.S11Amplitude));
                ui.dataTableWidget->setItem(i, 2, new QTableWidgetItem(item.S11Phase));
                ui.dataTableWidget->setItem(i, 3, new QTableWidgetItem(item.S21Amplitude));
                ui.dataTableWidget->setItem(i, 4, new QTableWidgetItem(item.S21Phase));
                ui.dataTableWidget->setItem(i, 5, new QTableWidgetItem(item.S12Amplitude));
                ui.dataTableWidget->setItem(i, 6, new QTableWidgetItem(item.S12Phase));
                ui.dataTableWidget->setItem(i, 7, new QTableWidgetItem(item.S22Amplitude));
                ui.dataTableWidget->setItem(i, 8, new QTableWidgetItem(item.S22Phase));
            }
        }
    }
}

bool import_gui::loadSetting()
{
    setDefaultExcelMapped();

    const QString section = "Mapped";
    const auto appDir = qApp->applicationDirPath();
    const auto iniFile = qApp->applicationDirPath() + "\\setting.ini";
    if (!QFile::exists(iniFile)) {
        QDir dir(appDir);
        if (!dir.exists()) {
            dir.mkpath(dir.absolutePath());
        }
        QFile file(iniFile);
        file.open(QFile::WriteOnly);
        file.close();
    }

    m_setting = new QSettings(iniFile, QSettings::IniFormat, this);
    m_setting->setIniCodec("UTF8");

    {
        auto key = QStringLiteral("Remote/ip");
        m_remoteIP = m_setting->value(key, constant::kRemoteIP).toString();
        key = QStringLiteral("Remote/port");
        m_remotePort = m_setting->value(key, constant::kRemotePort).toString();
        key = QStringLiteral("Local/ip");
        m_localIP = m_setting->value(key, constant::kLocalIP).toString();
        key = QStringLiteral("Share/dir");
        m_shareDir = m_setting->value(key, "").toString();
    }

    for (auto i = static_cast<unsigned int>(ItemIndex::Start) + 1; i < static_cast<unsigned int>(ItemIndex::End); ++i) {
        auto defaultValue = QString::number(i);
        auto key = section + "/" + QString::number(i);
        auto value = m_setting->value(key, defaultValue).toString();
        m_fileMapped.insert(static_cast<ItemIndex>(i), value);
        qDebug() << QString("%1: %2").arg(key).arg(value);
    }

    return true;
}

bool import_gui::saveSetting()
{
    try {
        const QString section = "Mapped";
        const auto appDir = qApp->applicationDirPath();
        const auto iniFile = qApp->applicationDirPath() + "\\setting.ini";
        if (!QFile::exists(iniFile)) {
            QDir dir(appDir);
            if (!dir.exists()) {
                dir.mkpath(dir.absolutePath());
            }
            QFile file(iniFile);
            file.open(QFile::WriteOnly);
            file.close();
        }

        m_setting = new QSettings(iniFile, QSettings::IniFormat, this);
        m_setting->setIniCodec("UTF8");

        {
            auto key = QStringLiteral("Remote/ip");
            m_setting->setValue(key, m_remoteIP);
            key = QStringLiteral("Remote/port");
            m_setting->setValue(key, m_remotePort);
            key = QStringLiteral("Local/ip");
            m_setting->setValue(key, m_localIP);
            key = QStringLiteral("Share/dir");
            m_setting->setValue(key, m_shareDir);
        }

        for (auto i = static_cast<unsigned int>(ItemIndex::Start) + 1; i < static_cast<unsigned int>(ItemIndex::End); ++i) {
            auto key = section + "/" + QString::number(i);
            m_setting->setValue(key, m_fileMapped[static_cast<ItemIndex>(i)]);
        }
    } catch (const std::exception&) {
        return false;
    }

    return true;
}

void import_gui::setDefaultExcelMapped()
{
    m_excelMapped.clear();
    m_excelMapped.insert(ItemIndex::I_SC_S_L, constant::kI_SC_S_L);
    m_excelMapped.insert(ItemIndex::I_SC_S_H, constant::kI_SC_S_H);
    m_excelMapped.insert(ItemIndex::I_SC_S_R, constant::kI_SC_S_R);
    m_excelMapped.insert(ItemIndex::I_SC_R_L, constant::kI_SC_R_L);
    m_excelMapped.insert(ItemIndex::I_SC_R_H, constant::kI_SC_R_H);
    m_excelMapped.insert(ItemIndex::I_SC_R_R, constant::kI_SC_R_R);
    m_excelMapped.insert(ItemIndex::Q_SC_S_L, constant::kQ_SC_S_L);
    m_excelMapped.insert(ItemIndex::Q_SC_S_H, constant::kQ_SC_S_H);
    m_excelMapped.insert(ItemIndex::Q_SC_S_R, constant::kQ_SC_S_R);
    m_excelMapped.insert(ItemIndex::Q_SC_R_L, constant::kQ_SC_R_L);
    m_excelMapped.insert(ItemIndex::Q_SC_R_H, constant::kQ_SC_R_H);
    m_excelMapped.insert(ItemIndex::Q_SC_R_R, constant::kQ_SC_R_R);
    m_excelMapped.insert(ItemIndex::SC_RS_TI_I_L, constant::kSC_RS_TI_I_L);
    m_excelMapped.insert(ItemIndex::SC_RS_TI_I_H, constant::kSC_RS_TI_I_H);
    m_excelMapped.insert(ItemIndex::SC_RS_TI_I_R, constant::kSC_RS_TI_I_R);
    m_excelMapped.insert(ItemIndex::SC_RS_TI_Q_L, constant::kSC_RS_TI_Q_L);
    m_excelMapped.insert(ItemIndex::SC_RS_TI_Q_H, constant::kSC_RS_TI_Q_H);
    m_excelMapped.insert(ItemIndex::SC_RS_TI_Q_R, constant::kSC_RS_TI_Q_R);
    m_excelMapped.insert(ItemIndex::I_X_S_L, constant::kI_X_S_L);
    m_excelMapped.insert(ItemIndex::I_X_S_H, constant::kI_X_S_H);
    m_excelMapped.insert(ItemIndex::I_X_S_R, constant::kI_X_S_R);
    m_excelMapped.insert(ItemIndex::I_X_R_L, constant::kI_X_R_L);
    m_excelMapped.insert(ItemIndex::I_X_R_H, constant::kI_X_R_H);
    m_excelMapped.insert(ItemIndex::I_X_R_R, constant::kI_X_R_R);
    m_excelMapped.insert(ItemIndex::Q_X_S_L, constant::kQ_X_S_L);
    m_excelMapped.insert(ItemIndex::Q_X_S_H, constant::kQ_X_S_H);
    m_excelMapped.insert(ItemIndex::Q_X_S_R, constant::kQ_X_S_R);
    m_excelMapped.insert(ItemIndex::Q_X_R_L, constant::kQ_X_R_L);
    m_excelMapped.insert(ItemIndex::Q_X_R_H, constant::kQ_X_R_H);
    m_excelMapped.insert(ItemIndex::Q_X_R_R, constant::kQ_X_R_R);
    m_excelMapped.insert(ItemIndex::X_RS_TI_I_L, constant::kX_RS_TI_I_L);
    m_excelMapped.insert(ItemIndex::X_RS_TI_I_H, constant::kX_RS_TI_I_H);
    m_excelMapped.insert(ItemIndex::X_RS_TI_I_R, constant::kX_RS_TI_I_R);
    m_excelMapped.insert(ItemIndex::X_RS_TI_Q_L, constant::kX_RS_TI_Q_L);
    m_excelMapped.insert(ItemIndex::X_RS_TI_Q_H, constant::kX_RS_TI_Q_H);
    m_excelMapped.insert(ItemIndex::X_RS_TI_Q_R, constant::kX_RS_TI_Q_R);
}

void import_gui::initMappedView()
{
    ui.fileMapTableWidget->clear();
    ui.fileMapTableWidget->setRowCount(static_cast<int>(ItemIndex::End) - 1);
    ui.fileMapTableWidget->setColumnCount(3);
    QStringList hHeaders;
    hHeaders << "数据项" << "映射" << "文件名称";
    ui.fileMapTableWidget->setHorizontalHeaderLabels(hHeaders);
    //ui.fileMapTableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
    ui.fileMapTableWidget->horizontalHeader()->setStretchLastSection(true);
    ui.fileMapTableWidget->verticalHeader()->setVisible(false);
    ui.fileMapTableWidget->setColumnWidth(0, 200);
    auto i = 0;
    for (int index = static_cast<int>(ItemIndex::Start) + 1; index < static_cast<int>(ItemIndex::End); ++index) {
        const auto itemIndex = static_cast<ItemIndex>(index);
        const auto dataItem = m_excelMapped[itemIndex];
        const auto fileBase = m_fileMapped[itemIndex];
        auto tableItem1 = new QTableWidgetItem(dataItem);
        auto tableItem2 = new QTableWidgetItem("<===>");
        auto tableItem3 = new QTableWidgetItem(fileBase);
        ui.fileMapTableWidget->setItem(i, 0, tableItem1);
        ui.fileMapTableWidget->setItem(i, 1, tableItem2);
        ui.fileMapTableWidget->setItem(i, 2, tableItem3);
        tableItem1->setFlags(tableItem1->flags() & ~Qt::ItemIsEditable);
        tableItem1->setTextAlignment(Qt::AlignCenter);
        tableItem2->setFlags(tableItem2->flags() & ~Qt::ItemIsEnabled);
        tableItem2->setTextAlignment(Qt::AlignCenter);

        ++i;
    }
}

QString import_gui::tempStatusString(const TempStatus status)
{
    QString str;
    switch (status) {
    case TempStatus::Low:
        str = "_低温";
        break;
    case TempStatus::High:
        str = "_高温";
        break;
    case TempStatus::Room:
        str = "_常温";
        break;
    default:
        break;
    }
    return str;
}

void import_gui::write_I_SC_S_L(QXlsx::Document* xlsxR, const ItemIndex& key, const int row, const Status sta)
{
    if (!xlsxR) return;

    {
        QMap<qulonglong, ImportDataItem> firstItems;
        bool bPhaseConsistency = false;
        const auto first = importedData.importItemsMap.firstKey();
        if (static_cast<unsigned int>(key) > static_cast<unsigned int>(first)) {
            bPhaseConsistency = true;
            firstItems = importedData.importItemsMap[first];
        }

        const auto importItems = importedData.importItemsMap[key];
        int col2700MHz = 3, col4450MHz = 4, col6200MHz = 5, col8000_12000MHz = 6,
            col1100MHz = 7, colPhaseConsistency = 8, colAntenna = 9, colPort = 10;
        double freq2700MHz = 0.; bool set2700MHz = false; qulonglong delta2700MHz = 0; //插损（dB）-- 2700MHz
        double freq4450MHz = 0.; bool set4450MHz = false; qulonglong delta4450MHz = 0; //插损（dB）-- 4450MHz
        double freq6200MHz = 0.; bool set6200MHz = false; qulonglong delta6200MHz = 0; //插损（dB）-- 6200MHz
        double freq8000_12000MHz = 0.; bool set8000_12000MHz = false; //抑制（dB）-- 8000-1200MHz
        double freq1100MHz = 0.; bool set1100MHz = false; qulonglong delta1100MHz = 0; //抑制（dB）-- 1100MHz
        double freqAntenna = 0.; bool setAntenna = false; //天线驻波比
        double freqPort = 0.; bool setPort = false; //端口驻波比
        bool setPhaseConsistency = false; double deltaPhaseConsistency = 0; //相位一致性

        qulonglong freqAntennaPortMin = 2700000000, freqAntennaPortMax = 6200000000;
        for (auto it = importItems.begin(); it != importItems.end(); ++it) {
            const auto key = it.key();
            const auto item = it.value();
            if (key == 0) continue;

            if (bPhaseConsistency) {
                const auto firstItem = firstItems.value(key);
                if (firstItem.valid) {
                    auto delta = qAbs(qAbs(item.S21Phase.toDouble()) - qAbs(firstItem.S21Phase.toDouble()));
                    if (!setPhaseConsistency
                        || deltaPhaseConsistency < delta) {
                        deltaPhaseConsistency = delta;
                        setPhaseConsistency = true;
                    }
                }
            }

            auto delta = qAbs(key - 2700000000);
            if (!set2700MHz
                || delta2700MHz > delta) {
                delta2700MHz = delta;
                freq2700MHz = item.S21Amplitude.toDouble();
                set2700MHz = true;
            }
            delta = qAbs(key - 4450000000);
            if (!set4450MHz
                || delta4450MHz > delta) {
                delta4450MHz = delta;
                freq4450MHz = item.S21Amplitude.toDouble();
                set4450MHz = true;
            }
            delta = qAbs(key - 6200000000);
            if (!set6200MHz
                || delta6200MHz > delta) {
                delta6200MHz = delta;
                freq6200MHz = item.S21Amplitude.toDouble();
                set6200MHz = true;
            }
            if (key >= 8000000000
                && key <= 12000000000) {
                const auto temp8000_12000MHz = qAbs(item.S21Amplitude.toDouble());
                if (!set8000_12000MHz
                    || freq8000_12000MHz > temp8000_12000MHz) {
                    freq8000_12000MHz = temp8000_12000MHz;
                    set8000_12000MHz = true;
                }
            }
            delta = qAbs(key - 1100000000);
            if (!set1100MHz
                || delta1100MHz > delta) {
                delta1100MHz = delta;
                freq1100MHz = qAbs(item.S21Amplitude.toDouble());
                set1100MHz = true;
            }
            if (key >= freqAntennaPortMin
                && key <= freqAntennaPortMax) {
                auto tempAntenna = item.S22Amplitude.toDouble();
                auto tempPort = item.S11Amplitude.toDouble();
                if (sta == Status::Receive) {
                    tempAntenna = item.S11Amplitude.toDouble();
                    tempPort = item.S22Amplitude.toDouble();
                }

                if (!setAntenna ||
                    freqAntenna < tempAntenna) {
                    setAntenna = true;
                    freqAntenna = tempAntenna;
                }
                if (!setPort ||
                    freqPort < tempPort) {
                    setPort = true;
                    freqPort = tempPort;
                }
            }
        }

        auto str = QString::number(freq2700MHz, 'f', 2);
        auto value = qAbs(str.toDouble());
        set2700MHz ? xlsxR->write(row, col2700MHz, value) : 0;

        auto str1 = QString::number(freq4450MHz, 'f', 2);
        auto value1 = qAbs(str1.toDouble());
        set4450MHz ? xlsxR->write(row, col4450MHz, value1) : 0;

        auto str2 = QString::number(freq6200MHz, 'f', 2);
        auto value2 = qAbs(str2.toDouble());
        set6200MHz ? xlsxR->write(row, col6200MHz, value2) : 0;

        auto str3 = QString::number(freq8000_12000MHz, 'f', 2);
        auto value3 = qAbs(str3.toDouble());
        set8000_12000MHz ? xlsxR->write(row, col8000_12000MHz, value3) : 0;

        auto str4 = QString::number(freq1100MHz, 'f', 2);
        auto value4 = qAbs(str4.toDouble());
        set1100MHz ? xlsxR->write(row, col1100MHz, value4) : 0;

        if (bPhaseConsistency
            && setPhaseConsistency) {
            auto str7 = QString::number(deltaPhaseConsistency, 'f', 2);
            auto value7 = qAbs(str7.toDouble());
            xlsxR->write(row, colPhaseConsistency, value7); //相位一致性
        } else {
            xlsxR->write(row, colPhaseConsistency, 0); //相位一致性
        }

        {
            bool ok = false;
            freqAntenna = calStandingWaveRatio(freqAntenna, &ok);
            if (ok) {
                auto str5 = QString::number(freqAntenna, 'f', 2);
                auto value5 = qAbs(str5.toDouble());
                setAntenna ? xlsxR->write(row, colAntenna, value5) : 0;
            } else {
                setAntenna ? xlsxR->write(row, colAntenna, "无效") : 0;
            }
        }

        {
            bool ok = false;
            freqPort = calStandingWaveRatio(freqPort, &ok);
            if (ok) {
                auto str6 = QString::number(freqPort, 'f', 2);
                auto value6 = qAbs(str6.toDouble());
                setPort ? xlsxR->write(row, colPort, value6) : 0;
            } else {
                setPort ? xlsxR->write(row, colPort, "无效") : 0;
            }
        }
    }
}

void import_gui::write_SC_RS_TI_I_L(QXlsx::Document* xlsxR, const ItemIndex& key, const int row, const Page pa)
{
    if (!xlsxR) return;

    {
        const auto importItems = importedData.importItemsMap[key];
        int colI = 4, colQ = 7;
        double freqI = 0.; bool setI = false; //X收发隔离度（dB）I
        double freqQ = 0.; bool setQ = false; //X收发隔离度（dB）Q

        qulonglong freqAntennaPortMin = 2700000000, freqAntennaPortMax = 6200000000;
        if (pa == Page::Second) {
            freqAntennaPortMin = 8000000000;
            freqAntennaPortMax = 12000000000;
        }
        for (auto it = importItems.begin(); it != importItems.end(); ++it) {
            const auto key = it.key();
            const auto& item = it.value();
            if (key == 0) continue;

            if (key >= freqAntennaPortMin
                && key <= freqAntennaPortMax) {
                auto tempI = qAbs(item.S21Amplitude.toDouble());
                auto tempQ = qAbs(item.S21Amplitude.toDouble());
                if (!setI ||
                    freqI > tempI) {
                    freqI = tempI;
                    setI = true;
                }
                if (!setQ ||
                    freqQ > tempQ) {
                    freqQ = tempQ;
                    setQ = true;
                }
            }
        }

        auto str = QString::number(freqI, 'f', 2);
        auto value = -(str.toDouble());
        setI ? xlsxR->write(row, colI, value) : 0;

        auto str1 = QString::number(freqQ, 'f', 2);
        auto value1 = -(str1.toDouble());
        setQ ? xlsxR->write(row, colQ, value1) : 0;
    }
}

void import_gui::write_I_X_S_L(QXlsx::Document* xlsxR, const ItemIndex& key, const int row, const Status sta)
{
    if (!xlsxR) return;

    {
        QMap<qulonglong, ImportDataItem> firstItems;
        bool bPhaseConsistency = false;
        const auto first = importedData.importItemsMap.firstKey();
        if (static_cast<unsigned int>(key) > static_cast<unsigned int>(first)) {
            bPhaseConsistency = true;
            firstItems = importedData.importItemsMap[first];
        }

        const auto importItems = importedData.importItemsMap[key];
        int col8000MHz = 3, col10000MHz = 4, col12000MHz = 5, col2700_6200MHz = 6,
            colAntenna = 7, colPhaseConsistency = 8, colPort = 9;
        double freq8000MHz = 0.; bool set8000MHz = false; qulonglong delta8000MHz = 0; //插损（dB）-- 8000MHz
        double freq10000MHz = 0.; bool set10000MHz = false; qulonglong delta10000MHz = 0; //插损（dB）-- 10000MHz
        double freq12000MHz = 0.; bool set12000MHz = false; qulonglong delta12000MHz = 0; //插损（dB）-- 12000MHz
        double freq2700_6200MHz = 0.; bool set2700_6200MHz = false; //抑制（dB）-- 2700_6200MHz
        double freqAntenna = 0.; bool setAntenna = false; //天线驻波比
        double freqPort = 0.; bool setPort = false; //端口驻波比
        bool setPhaseConsistency = false; double deltaPhaseConsistency = 0; //相位一致性

        qulonglong freqAntennaPortMin = 8000000000, freqAntennaPortMax = 12000000000;
        for (auto it = importItems.begin(); it != importItems.end(); ++it) {
            const auto key = it.key();
            const auto& item = it.value();
            if (key == 0) continue;

            if (bPhaseConsistency) {
                const auto firstItem = firstItems.value(key);
                if (firstItem.valid) {
                    auto delta = qAbs(qAbs(item.S21Phase.toDouble()) - qAbs(firstItem.S21Phase.toDouble()));
                    if (!setPhaseConsistency
                        || deltaPhaseConsistency < delta) {
                        deltaPhaseConsistency = delta;
                        setPhaseConsistency = true;
                    }
                }
            }

            auto delta = qAbs(key - 8000000000);
            if (!set8000MHz
                || delta8000MHz > delta) {
                delta8000MHz = delta;
                freq8000MHz = item.S21Amplitude.toDouble();
                set8000MHz = true;
            }
            delta = qAbs(key - 10000000000);
            if (!set10000MHz
                || delta10000MHz > delta) {
                delta10000MHz = delta;
                freq10000MHz = item.S21Amplitude.toDouble();
                set10000MHz = true;
            }
            delta = qAbs(key - 12000000000);
            if (!set12000MHz
                || delta12000MHz > delta) {
                delta12000MHz = delta;
                freq12000MHz = item.S21Amplitude.toDouble();
                set12000MHz = true;
            }
            if (key >= 2700000000
                && key <= 6200000000) {
                const auto temp8000_12000MHz = qAbs(item.S21Amplitude.toDouble());
                if (!set2700_6200MHz
                    || freq2700_6200MHz > temp8000_12000MHz) {
                    freq2700_6200MHz = temp8000_12000MHz;
                    set2700_6200MHz = true;
                }
            }
            if (key >= freqAntennaPortMin
                && key <= freqAntennaPortMax) {
                auto tempAntenna = item.S22Amplitude.toDouble();
                auto tempPort = item.S11Amplitude.toDouble();
                if (sta == Status::Receive) {
                    tempAntenna = item.S11Amplitude.toDouble();
                    tempPort = item.S22Amplitude.toDouble();
                }

                if (!setAntenna ||
                    freqAntenna < tempAntenna) {
                    setAntenna = true;
                    freqAntenna = tempAntenna;
                }
                if (!setPort ||
                    freqPort < tempPort) {
                    setPort = true;
                    freqPort = tempPort;
                }
            }
        }

        auto str = QString::number(freq8000MHz, 'f', 2);
        auto value = qAbs(str.toDouble());
        set8000MHz ? xlsxR->write(row, col8000MHz, value) : 0;

        auto str1 = QString::number(freq10000MHz, 'f', 2);
        auto value1 = qAbs(str1.toDouble());
        set10000MHz ? xlsxR->write(row, col10000MHz, value1) : 0;

        auto str2 = QString::number(freq12000MHz, 'f', 2);
        auto value2 = qAbs(str2.toDouble());
        set12000MHz ? xlsxR->write(row, col12000MHz, value2) : 0;

        auto str3 = QString::number(freq2700_6200MHz, 'f', 2);
        auto value3 = qAbs(str3.toDouble());
        set2700_6200MHz ? xlsxR->write(row, col2700_6200MHz, value3) : 0;

        {
            bool ok = false;
            freqAntenna = calStandingWaveRatio(freqAntenna, &ok);
            if (ok) {
                auto str4 = QString::number(freqAntenna, 'f', 2);
                auto value4 = qAbs(str4.toDouble());
                setAntenna ? xlsxR->write(row, colAntenna, value4) : 0;
            } else {
                setAntenna ? xlsxR->write(row, colAntenna, "无效") : 0;
            }
        }

        if (bPhaseConsistency
            && setPhaseConsistency) {
            auto str7 = QString::number(deltaPhaseConsistency, 'f', 2);
            auto value7 = qAbs(str7.toDouble());
            xlsxR->write(row, colPhaseConsistency, value7); //相位一致性
        } else {
            xlsxR->write(row, colPhaseConsistency, 0); //相位一致性
        }

        {
            bool ok = false;
            freqPort = calStandingWaveRatio(freqPort, &ok);
            if (ok) {
                auto str5 = QString::number(freqPort, 'f', 2);
                auto value5 = qAbs(str5.toDouble());
                setPort ? xlsxR->write(row, colPort, value5) : 0;
            } else {
                setPort ? xlsxR->write(row, colPort, "无效") : 0;
            }
        }
    }
}

bool import_gui::cardSendCommand(const ItemIndex& index)
{
    if (hDev == INVALID_HANDLE_VALUE) return false;

    bool rtn = true;
    switch (index) {
    case ItemIndex::I_SC_S_L:
    case ItemIndex::I_SC_S_H:
    case ItemIndex::I_SC_S_R:
    {
        FY5400_DO(hDev, 0);//全关
        FY5400_DO_Bit(hDev, 1, 0);
        FY5400_DO_Bit(hDev, 1, 10);
        FY5400_DO_Bit(hDev, 1, 12);
    }
    break;
    case ItemIndex::I_X_S_L:
    case ItemIndex::I_X_S_H:
    case ItemIndex::I_X_S_R:
    {
        FY5400_DO(hDev, 0);//全关
        FY5400_DO_Bit(hDev, 1, 1);
        FY5400_DO_Bit(hDev, 1, 10);
        FY5400_DO_Bit(hDev, 1, 12);
    }
    break;
    case ItemIndex::Q_SC_S_L:
    case ItemIndex::Q_SC_S_H:
    case ItemIndex::Q_SC_S_R:
    {
        FY5400_DO(hDev, 0);//全关
        FY5400_DO_Bit(hDev, 1, 2);
        FY5400_DO_Bit(hDev, 1, 11);
        FY5400_DO_Bit(hDev, 1, 13);
    }
    break;
    case ItemIndex::Q_X_S_L:
    case ItemIndex::Q_X_S_H:
    case ItemIndex::Q_X_S_R:
    {
        FY5400_DO(hDev, 0);//全关
        FY5400_DO_Bit(hDev, 1, 3);
        FY5400_DO_Bit(hDev, 1, 11);
        FY5400_DO_Bit(hDev, 1, 13);
    }
    break;
    case ItemIndex::I_SC_R_L:
    case ItemIndex::I_SC_R_H:
    case ItemIndex::I_SC_R_R:
    {
        FY5400_DO(hDev, 0);//全关
        FY5400_DO_Bit(hDev, 1, 4);
        FY5400_DO_Bit(hDev, 1, 6);
        FY5400_DO_Bit(hDev, 1, 12);
        FY5400_DO_Bit(hDev, 1, 14);
    }
    break;
    case ItemIndex::I_X_R_L:
    case ItemIndex::I_X_R_H:
    case ItemIndex::I_X_R_R:
    {
        FY5400_DO(hDev, 0);//全关
        FY5400_DO_Bit(hDev, 1, 4);
        FY5400_DO_Bit(hDev, 1, 7);
        FY5400_DO_Bit(hDev, 1, 12);
        FY5400_DO_Bit(hDev, 1, 14);
    }
    break;
    case ItemIndex::Q_SC_R_L:
    case ItemIndex::Q_SC_R_H:
    case ItemIndex::Q_SC_R_R:
    {
        FY5400_DO(hDev, 0);//全关
        FY5400_DO_Bit(hDev, 1, 5);
        FY5400_DO_Bit(hDev, 1, 8);
        FY5400_DO_Bit(hDev, 1, 13);
        FY5400_DO_Bit(hDev, 1, 15);
    }
    break;
    case ItemIndex::Q_X_R_L:
    case ItemIndex::Q_X_R_H:
    case ItemIndex::Q_X_R_R:
    {
        FY5400_DO(hDev, 0);//全关
        FY5400_DO_Bit(hDev, 1, 5);
        FY5400_DO_Bit(hDev, 1, 9);
        FY5400_DO_Bit(hDev, 1, 13);
        FY5400_DO_Bit(hDev, 1, 15);
    }
    break;
    case ItemIndex::SC_RS_TI_I_L:
    case ItemIndex::SC_RS_TI_I_H:
    case ItemIndex::SC_RS_TI_I_R:
    {
        FY5400_DO(hDev, 0);//全关
        FY5400_DO_Bit(hDev, 1, 0);
        FY5400_DO_Bit(hDev, 1, 6);
    }
    break;
    case ItemIndex::X_RS_TI_I_L:
    case ItemIndex::X_RS_TI_I_H:
    case ItemIndex::X_RS_TI_I_R:
    {
        FY5400_DO(hDev, 0);//全关
        FY5400_DO_Bit(hDev, 1, 1);
        FY5400_DO_Bit(hDev, 1, 7);
    }
    break;
    case ItemIndex::SC_RS_TI_Q_L:
    case ItemIndex::SC_RS_TI_Q_H:
    case ItemIndex::SC_RS_TI_Q_R:
    {
        FY5400_DO(hDev, 0);//全关
        FY5400_DO_Bit(hDev, 1, 2);
        FY5400_DO_Bit(hDev, 1, 8);
    }
    break;
    case ItemIndex::X_RS_TI_Q_L:
    case ItemIndex::X_RS_TI_Q_H:
    case ItemIndex::X_RS_TI_Q_R:
    {
        FY5400_DO(hDev, 0);//全关
        FY5400_DO_Bit(hDev, 1, 3);
        FY5400_DO_Bit(hDev, 1, 9);
    }
    break;
    default:
    {
        rtn = false;
    }
    break;
    }

    return rtn;
}

double import_gui::calStandingWaveRatio(double dValue, bool* ok)
{
    double temp = qPow(10., dValue / 20.);

    if (qFuzzyCompare(temp, 1.)) {
        if (ok) {
            ok = false;
        }
        return dValue;
    }

    if (ok) {
        *ok = true;
    }
    return (1. + temp) / (1. - temp);
}

void import_gui::selectShareDir()
{
    QFileDialog dialog(this, "选择本地共享文件夹");
    dialog.setAcceptMode(QFileDialog::AcceptOpen);
    dialog.setFileMode(QFileDialog::DirectoryOnly);
    QUrl url;
    bool rtn = false;
    if (dialog.exec()) {
        auto urls = dialog.selectedUrls();
        if (urls.size() > 0) {
            url = urls[0];
            rtn = true;
        }
    }

    if (!rtn
        && !url.isValid()) return;

    auto dir = url.toLocalFile();
    const auto list = dir.split('/');
    if (list.size() > 0) {
        m_shareDir = list.last();
        ui.shareDirLineEdit->setText(m_shareDir);
        auto configString = QString("TCPIP0::%1::inst0::INSTR,'\\\\%2\\%3\\%4.s2p'")
            .arg(m_remoteIP).arg(m_localIP).arg(m_shareDir).arg(m_fileMapped.value(m_currentImportIndex));
        ui.configLineEdit->setText(configString);
        saveSetting();
    }
}

void import_gui::importFromRemote()
{
    if (m_remoteIP.isEmpty()
        || m_remoteIP.isNull()) {
        QMessageBox::information(this, "错误", "远程设备IP不正确!");
        return;
    }
    if (m_localIP.isEmpty()
        || m_localIP.isNull()) {
        QMessageBox::information(this, "错误", "本地设备IP不正确!");
        return;
    }
    if (m_shareDir.isEmpty()
        || m_shareDir.isNull()) {
        QMessageBox::information(this, "错误", "共享文件夹设置不正确!");
        return;
    }
    if (static_cast<unsigned int>(m_currentImportIndex) <= static_cast<unsigned int>(ItemIndex::Start)
        || static_cast<unsigned int>(m_currentImportIndex) >= static_cast<unsigned int>(ItemIndex::End)) {
        QMessageBox::information(this, "错误", "导入的项不正确!");
        return;
    }

    if (QFile::exists(m_configName)) {
        auto configString = QString("TCPIP0::%1::inst0::INSTR,'\\\\%2\\%3\\%4.s2p'")
            .arg(m_remoteIP).arg(m_localIP).arg(m_shareDir).arg(m_fileMapped.value(m_currentImportIndex));
        QFile file(m_configName);
        file.open(QIODevice::WriteOnly);
        QTextStream out(&file);
        out << configString;
        file.flush();
        file.close();

        m_toolProcess->start(m_toolName);
        m_toolProcess->waitForFinished();
    }
}

void import_gui::tempStatusToggled(int id)
{
    m_tempStatus = static_cast<TempStatus>(id);
    auto excelText = ui.selectComboBox->currentText() + tempStatusString(m_tempStatus);
    auto it = m_excelMapped.key(excelText);
    if (it != ItemIndex()) {
        m_currentImportIndex = it;
        auto configString = QString("TCPIP0::%1::inst0::INSTR,'\\\\%2\\%3\\%4.s2p'")
            .arg(m_remoteIP).arg(m_localIP).arg(m_shareDir).arg(m_fileMapped.value(m_currentImportIndex));
        ui.configLineEdit->setText(configString);
    }
}

void import_gui::selectCurrentIndexChangedHandler(const QString& value)
{
    auto excelText = value + tempStatusString(m_tempStatus);
    auto it = m_excelMapped.key(excelText);
    if (it != ItemIndex()) {
        m_currentImportIndex = it;
        auto configString = QString("TCPIP0::%1::inst0::INSTR,'\\\\%2\\%3\\%4.s2p'")
            .arg(m_remoteIP).arg(m_localIP).arg(m_shareDir).arg(m_fileMapped.value(m_currentImportIndex));
        ui.configLineEdit->setText(configString);

        if (cardSendCommand(m_currentImportIndex)) {
            ui.sendStatusLabel->setText("发送成功: " + value);
            ui.sendStatusLabel->setStyleSheet(QString::fromUtf8("color: rgb(0, 85, 255);"));
        } else {
            ui.sendStatusLabel->setText("发送失败: " + value);
            ui.sendStatusLabel->setStyleSheet(QString::fromUtf8("color: rgb(255, 0, 0);"));
        }
    }
}

import_gui::~import_gui()
{
    if (m_xlsxR) {
        delete m_xlsxR;
        m_xlsxR = nullptr;
    }
    m_tcpClient->abort();
}

void import_gui::setStyle(import_gui::Style style)
{
    QString qssFile = ":/qss/blue.css";

    if (style == import_gui::Style_Silvery) {
        qssFile = ":/qss/silvery.css";
    } else if (style == import_gui::Style_Blue) {
        qssFile = ":/qss/blue.css";
    } else if (style == import_gui::Style_LightBlue) {
        qssFile = ":/qss/lightblue.css";
    } else if (style == import_gui::Style_DarkBlue) {
        qssFile = ":/qss/darkblue.css";
    } else if (style == import_gui::Style_Gray) {
        qssFile = ":/qss/gray.css";
    } else if (style == import_gui::Style_LightGray) {
        qssFile = ":/qss/lightgray.css";
    } else if (style == import_gui::Style_DarkGray) {
        qssFile = ":/qss/darkgray.css";
    } else if (style == import_gui::Style_Black) {
        qssFile = ":/qss/black.css";
    } else if (style == import_gui::Style_LightBlack) {
        qssFile = ":/qss/lightblack.css";
    } else if (style == import_gui::Style_DarkBlack) {
        qssFile = ":/qss/darkblack.css";
    } else if (style == import_gui::Style_PSBlack) {
        qssFile = ":/qss/psblack.css";
    } else if (style == import_gui::Style_FlatBlack) {
        qssFile = ":/qss/flatblack.css";
    } else if (style == import_gui::Style_FlatWhite) {
        qssFile = ":/qss/flatwhite.css";
    }

    QFile file(qssFile);

    if (file.open(QFile::ReadOnly)) {
        QString qss = QLatin1String(file.readAll());
        QString paletteColor = qss.mid(20, 7);
        qApp->setPalette(QPalette(QColor(paletteColor)));
        qApp->setStyleSheet(qss);
        //saveSetting();
        file.close();
    }
}

void import_gui::onConnected()
{
    //connected()信号槽函数
    ui.textPlainTextEdit->appendPlainText("**已连接网络仪");
    ui.textPlainTextEdit->appendPlainText("**  IP地址:" + m_tcpClient->peerAddress().toString());
    ui.textPlainTextEdit->appendPlainText("** 端  口:" + QString::number(m_tcpClient->peerPort()));
}

void import_gui::onSocketReadyRead()
{
    //readyRead()信号槽函数
    while (m_tcpClient->canReadLine())
        ui.textPlainTextEdit->appendPlainText("[in] " + m_tcpClient->readLine());
}

void import_gui::onSocketStateChange(QAbstractSocket::SocketState socketState)
{
    //stateChange()信号槽函数
    switch (socketState) {
    case QAbstractSocket::UnconnectedState:
    {
        ui.textPlainTextEdit->appendPlainText("scoket状态：没有连接");
        ui.tcpStatusLabel->setText("未连接");
        ui.tcpStatusLabel->setStyleSheet(QString::fromUtf8("color: rgb(255, 0, 0);"));
    }
    break;
    case QAbstractSocket::HostLookupState:
    {
        ui.textPlainTextEdit->appendPlainText("scoket状态：主机查找状态");
        ui.tcpStatusLabel->setText("主机名查找中");
        ui.tcpStatusLabel->setStyleSheet(QString::fromUtf8("color: rgb(0, 85, 255);"));
    }
    break;
    case QAbstractSocket::ConnectingState:
    {
        ui.textPlainTextEdit->appendPlainText("scoket状态：正在连接......");
        ui.tcpStatusLabel->setText("开始建立连接");
        ui.tcpStatusLabel->setStyleSheet(QString::fromUtf8("color: rgb(0, 85, 255);"));
    }
    break;

    case QAbstractSocket::ConnectedState:
    {
        ui.textPlainTextEdit->appendPlainText("scoket状态：已连接");
        ui.stateComboBox->setEnabled(true);
        ui.commandComboBox->setEnabled(true);
        ui.statePushButton->setEnabled(true);
        ui.commandPushButton->setEnabled(true);
        ui.clearPushButton->setEnabled(true);
        ui.tcpStatusLabel->setText("已连接");
        ui.tcpStatusLabel->setStyleSheet(QString::fromUtf8("color: rgb(0, 85, 255);"));
    }
    break;

    case QAbstractSocket::BoundState:
    {
        ui.tcpStatusLabel->setText("已连接");
        ui.tcpStatusLabel->setStyleSheet(QString::fromUtf8("color: rgb(0, 85, 255);"));
    }
    break;

    case QAbstractSocket::ClosingState:
    {
        ui.textPlainTextEdit->appendPlainText("scoket状态：关闭状态");
        ui.tcpStatusLabel->setText("关闭中");
        ui.tcpStatusLabel->setStyleSheet(QString::fromUtf8("color: rgb(0, 85, 255);"));
    }
    break;

    case QAbstractSocket::ListeningState:
        break;
    }
}